package com.acxy.pay.weixin;

import com.acxy.ants.common.kit.*;
import com.acxy.ants.core.annotation.Service;
import com.acxy.ants.core.annotation.Value;
import com.acxy.ants.core.kit.LogKit;

import java.io.InputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;

/**
 * 订单业务接口
 * 拉取评论好像有点点问题
 * @author MrShun
 * @version 1.0
 * @Date 2017-11-05
 */
@Service
public class OrderService {

    @Value("wx.appId")
    private String appId;

    @Value("wx.mchId")
    private String mchId;

    @Value("wx.payKey")
    private String payKey;

    @Value("wx.cert")
    private String cert;

    /**
     * 查询订单接口
     * POST 发送xml数据
     */
    private final static String unifiedOrderURL = "https://api.mch.weixin.qq.com/pay/orderquery";

    /**
     * 关闭订单接口
     * POST 发送xml数据
     */
    public final static String closeOrderURL = "https://api.mch.weixin.qq.com/pay/closeorder";

    /**
     * 申请退款，需要双向证书
     * POST 发送xml数据
     */
    private final static String refundURL = "https://api.mch.weixin.qq.com/secapi/pay/refund";

    /**
     * 申请退款，需要双向证书
     * POST 发送xml数据
     */
    private final static String refundQueryURL = "https://api.mch.weixin.qq.com/pay/refundquery";

    /**
     * 下载对账单
     */
    private final static String downLoadBillURL = "https://api.mch.weixin.qq.com/pay/downloadbill";

    /**
     * 评价列表查询
     */
    private final static String batchQueryCommentURL = "https://api.mch.weixin.qq.com/billcommentsp/batchquerycomment";


    /**
     * 查询订单, 关闭订单, 查询退款订单
     *
     * @param id   商户订单号
     * @param type 0/查询订单 1/关闭订单 2/查询退款订单
     * @return
     */
    public Map getWxOrder(String id, int type) {
        PayParams params = PayParams.newPayParams()
                .setAppId(appId)
                .setMchId(mchId)
                .setNonceStr(StrKit.randomUUID())
                .setOutTradeNo(id);
        params.setSign(Sign.md5Sign(params, payKey));
        String xml = MapXmlKit.map2Xml(params, "xml");
        String url = unifiedOrderURL;
        if (type == 1)
            url = closeOrderURL;
        else if (type == 2)
            url = refundQueryURL;
        String responseXml = HttpKit.sendPost(url, xml);
        return MapXmlKit.xml2Map(responseXml, "xml");
    }


    /**
     * 申请退款, 需要双向证书
     *
     * @param id          商户订单ID
     * @param totalFee    总金额
     * @param outRefundNo 退款单号
     * @param refundFee   退款金额
     * @return
     */
    public Map refund(String id, String totalFee, String outRefundNo, String refundFee) {
        //总金额
        BigDecimal total_money = new BigDecimal(totalFee).multiply(new BigDecimal(100));
        BigInteger total_fee = (total_money).setScale(0, BigDecimal.ROUND_HALF_UP).toBigInteger();
        PayParams params = PayParams.newPayParams()
                .setAppId(appId)
                .setMchId(mchId)
                .setNonceStr(StrKit.randomUUID())
                .setOutTradeNo(id)
                .setTotalFee(total_fee);
        params.put("out_refund_no", outRefundNo);
        //返还金额
        BigDecimal refund_money = new BigDecimal(refundFee).multiply(new BigDecimal(100));
        BigInteger refund_fee = (refund_money).setScale(0, BigDecimal.ROUND_HALF_UP).toBigInteger();
        params.put("refund_fee", refund_fee);
        params.setSign(Sign.md5Sign(params, payKey));
        String xml = MapXmlKit.map2Xml(params, "xml");
        String responseXml = SSLHttpRequest.p12Send(refundURL, xml, cert, mchId);
        return MapXmlKit.xml2Map(responseXml, "xml");
    }

    /**
     * 载对账单
     *
     * @param billDate 下载对账单的日期，格式：20140603
     * @param type     类型 ALL(返回当日所有订单信息，默认值), SUCCESS("返回当日成功支付的订单"),REFUND("返回当日退款订单"),RECHARGE_REFUND("返回当日充值退款订单");
     * @return 返回流对象
     */
    public Object downLoadBill(String billDate, String type) {
        PayParams params = PayParams.newPayParams()
                .setAppId(appId)
                .setMchId(mchId)
                .setNonceStr(StrKit.randomUUID());
        params.put("bill_date", billDate);
        params.put("bill_type", type);
        params.setSign(Sign.md5Sign(params, payKey));
        String xml = MapXmlKit.map2Xml(params, "xml");
        System.out.println(xml);
        return HttpKit.sendPost(downLoadBillURL, xml);
    }

    /**
     * 拉取订单评价数据
     *
     * @param offset    指定某条记录
     * @param limit     每页大小
     * @param beginTime 开始时间 格式为yyyyMMddHHmmss
     * @param endTime   开始时间 格式为yyyyMMddHHmmss
     * @return
     */
    public Map batchQueryComment(int offset, int limit, String beginTime, String endTime) {
        PayParams params = PayParams.newPayParams()
                .setAppId(appId)
                .setMchId(mchId)
                .setNonceStr(StrKit.randomUUID());
        params.put("offset", offset);
        params.put("limit", limit);
        params.put("begin_time", beginTime);
        params.put("end_time", endTime);
        params.put("sign_type", "HMAC-SHA256");
        params.setSign(Sign.hmacSha256Sign(params, payKey));
        String xml = MapXmlKit.map2Xml(params, "xml");
        System.err.println("xml:" + xml);
        String responseXml = SSLHttpRequest.p12Send(batchQueryCommentURL, xml, cert, mchId);
        return MapXmlKit.xml2Map(responseXml, "xml");
    }


    /**
     * 解密退款通知相应数据
     *
     * @param in 数据 根节点是root
     * @return
     */
    public Map refundNotifyUrl(InputStream in) throws Exception {
        String body = IOKit.parseStr(in);
        Map res = MapXmlKit.xml2Map(body, "xml");
        if ("SUCCESS".equals(res.get("return_code"))) {
            byte[] bytes = Base64Kit.decodeBase64(String.valueOf(res.get("req_info")));
            String key = StrEncryptKit.MD5(payKey);
            String result = Aes.AesEcbDecode(bytes, key);
            return MapXmlKit.xml2Map(result, "root");
        } else
            return res;
    }
}
